// $Id: pstring_ref.cpp 2 2009-09-02 08:47:42Z joseph2002 $
/*
 * Copyright 2009 Joseph Wu
 * Distributed under the Boost Software License, Version 1.0.
 * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
 *
 * For more information, see http://xpcomplus.sourceforge.net
 */

#include <cstring>
#include <boost/test/unit_test.hpp>
#include <xpcom/string.hpp>
#include <xpcom/proxy/pstring_ref.hpp>

BOOST_AUTO_TEST_CASE(test_pstring_ref_cons)
{
    using namespace xpcom;
    using namespace xpcom::proxy;

    typedef pstring_ref<char> Psr;

    const char* s1 = "test1";
    const char* s2 = "test2";
    const char* s3 = "test3";
    const char* ss = "";

    Psr p;
    BOOST_CHECK(!p);
    BOOST_CHECK(p.get() == 0);

    Psr pp(0);
    BOOST_CHECK(!pp);
    BOOST_CHECK(pp.get() == 0);

    Psr p1(s1);
    BOOST_CHECK(p1);
    BOOST_CHECK(p1.get() != 0);
    BOOST_CHECK(p1.get() != s1);
    BOOST_CHECK(std::strcmp(p1, s1) == 0);

    Psr p2(s1, 3);
    BOOST_CHECK(p2);
    BOOST_CHECK(p2.get() != 0);
    BOOST_CHECK(p2.get() != s1);
    BOOST_CHECK(std::strcmp(p2, s1) != 0);
    BOOST_CHECK(std::strlen(p2) == 3);
    BOOST_CHECK(std::strcmp(p2, "tes") == 0);

    Psr p3(s2);
    Psr p4(p3);
    BOOST_CHECK(p4);
    BOOST_CHECK(p4.get() != 0);
    BOOST_CHECK(p4.get() != s2);
    BOOST_CHECK(std::strcmp(p4, s2) == 0);

    string s = s3;
    Psr p5(s);
    BOOST_CHECK(p5);
    BOOST_CHECK(p5.get() != 0);
    BOOST_CHECK(std::strcmp(p5, s3) == 0);

    s.clear();
    Psr p6(s);
    BOOST_CHECK(!p6);
    BOOST_CHECK(p6.get() == 0);

    Psr p7(ss);
    BOOST_CHECK(p7);
    BOOST_CHECK(p7.get() != 0);
    BOOST_CHECK(std::strlen(p7) == 0);
    BOOST_CHECK(std::strcmp(p7, "") == 0);
}

BOOST_AUTO_TEST_CASE(test_pstring_ref_assign)
{
    using namespace xpcom;
    using namespace xpcom::proxy;

    typedef pstring_ref<char> Psr;

    const char* s1 = "test1";
    const char* s2 = "test2";
    const char* s3 = "test3";
    const char* ss = "";

    Psr p;

    p = s1;
    BOOST_CHECK(p);
    BOOST_CHECK(p.get() != 0);
    BOOST_CHECK(p.get() != s1);
    BOOST_CHECK(std::strcmp(p, s1) == 0);

    p.assign(s1, 3);
    BOOST_CHECK(p);
    BOOST_CHECK(p.get() != 0);
    BOOST_CHECK(p.get() != s1);
    BOOST_CHECK(std::strcmp(p, s1) != 0);
    BOOST_CHECK(std::strlen(p) == 3);
    BOOST_CHECK(std::strcmp(p, "tes") == 0);

    Psr p2;
    p2 = s2;
    p = p2;
    BOOST_CHECK(p);
    BOOST_CHECK(p.get() != 0);
    BOOST_CHECK(p.get() != s2);
    BOOST_CHECK(std::strcmp(p, s2) == 0);

    string s = s3;
    p = s;
    BOOST_CHECK(p);
    BOOST_CHECK(p.get() != 0);
    BOOST_CHECK(std::strcmp(p, s3) == 0);

    p = ss;
    BOOST_CHECK(p);
    BOOST_CHECK(p.get() != 0);
    BOOST_CHECK(std::strlen(p) == 0);
    BOOST_CHECK(std::strcmp(p, "") == 0);

    p = 0;
    BOOST_CHECK(!p);
    BOOST_CHECK(p.get() == 0);
}

BOOST_AUTO_TEST_CASE(test_pstring_ref_compare)
{
    using namespace xpcom;
    using namespace xpcom::proxy;

    typedef pstring_ref<char> Psr;

    const char* s1 = "test1";
    const char* s2 = "test2";
    const char* s3 = "test3";
    const char* ss = "";

    Psr p;

    p = s1;
    BOOST_CHECK(p.equal(s1));
    BOOST_CHECK(p == s1);
    BOOST_CHECK(s1 == p);

    p.assign(s1, 3);
    BOOST_CHECK(!p.equal(s1));
    BOOST_CHECK(p.equal(s2, 3));
    BOOST_CHECK(!(s1 == p));
    BOOST_CHECK(p != s1);
    BOOST_CHECK("tes" == p);

    Psr p2;
    p2 = s2;
    BOOST_CHECK(!p.equal(p2));
    BOOST_CHECK(p != p2);
    p = p2;
    BOOST_CHECK(p.equal(p2));
    BOOST_CHECK(p == p2);

    string s = s3;
    p = s;
    BOOST_CHECK(p.equal(s));
    BOOST_CHECK(p == s);
    BOOST_CHECK(s == p);
    s = "test";
    BOOST_CHECK(!p.equal(s));
    BOOST_CHECK(p != s);
    BOOST_CHECK(!(s == p));

    Psr pp;
    BOOST_CHECK(!pp.equal(ss));
    BOOST_CHECK(pp != "");
    BOOST_CHECK(pp == string());
    BOOST_CHECK(pp != p);
    BOOST_CHECK(pp != p2);
    BOOST_CHECK(pp == 0);
    BOOST_CHECK(pp.equal(0));

    Psr ppp;
    BOOST_CHECK(pp == ppp);
    BOOST_CHECK(pp.equal(ppp));
}

BOOST_AUTO_TEST_CASE(test_pstring_ref_swap)
{
    using namespace xpcom;
    using namespace xpcom::proxy;

    typedef pstring_ref<char> Psr;

    const char* s1 = "test1";
    const char* s2 = "test2";

    Psr p1;
    Psr p2;

    BOOST_CHECK(p1.get() == 0);
    BOOST_CHECK(p2.get() == 0);

    p1.swap(p2);
    BOOST_CHECK(p1.get() == 0);
    BOOST_CHECK(p2.get() == 0);

    p1 = s1;
    BOOST_CHECK(std::strcmp(p1, s1) == 0);
    p1.swap(p2);
    BOOST_CHECK(p1.get() == 0);
    BOOST_CHECK(std::strcmp(p2, s1) == 0);

    p1 = s2;
    BOOST_CHECK(std::strcmp(p1, s2) == 0);
    p1.swap(p2);
    BOOST_CHECK(std::strcmp(p1, s1) == 0);
    BOOST_CHECK(std::strcmp(p2, s2) == 0);
}
